/**
 *	The NeuroCoSA Toolkit
 *	Copyright (C) 2003-6 Stuart Meikle.
 *
 *	This is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *	Lesser General Public License for more details.
 *
 * @author	Stuart Meikle
 * @version	2006-halloween(mk2)
 * @license	LGPL
 */
package org.stumeikle.NeuroCoSA;


// demo user classes
import java.util.*;
import java.lang.*;
import org.stumeikle.NeuroCoSA.AutoCluster.AutoClusterMemoryControl;
import org.stumeikle.NeuroCoSA.AutoCluster.AutoClusterMemory;


/**
 *  A neuron which sums and weights the inputs in order to determine its own state
 *  Special in the sense that neuron will be driven by all incoming synapses and not 
 *  a single synapse. (IE drive controller idea kind of goes out the winder)
 */
public class TradNeuron extends SimpleNeuron 
{
    String			iDbg;
    double			iDriveTotalWeight;
    double			iLearnTotalWeight;
    double			iDriveThreshold;
    double			iLearnThreshold;
    
    public TradNeuron(Layer l)
    {
	super(l);
	String	t = new String( "" + this);
	t = t.replaceAll("org.stumeikle.NeuroCoSA.", "");

	iDbg = new String(t);
	setDrivesMustCompete(false);// learn and drive signals collaborate to trigger this neuron
	iDriveTotalWeight = iLearnTotalWeight = 0.0;
	iDriveThreshold = 1.9; //we need two inputs to trigger in this case. v simple
	iLearnThreshold = 1.9; //we need two inputs to trigger in this case. v simple
    }

    public	String		getDEBUGLabel()	
    {
	//should be overloaded by the user
	return iDbg;
    }

    public DataBlock		createCortexOutput(boolean l)
    {
	return null;
    }

    public	void		startOfVesicleProcessing()
    {
	//reset the summation vars
	iDriveTotalWeight = iLearnTotalWeight = 0.0;
    }

    public	void		endOfVesicleProcessing()
    {
	//translate the summation vars into a drive and learn signal strength
	if (iLearnTotalWeight > iLearnThreshold)
	    simpleUpdateLearnSig( iLearnTotalWeight /2.0, null );
	if (iDriveTotalWeight > iDriveThreshold)
	    simpleUpdateDriveSig( iDriveTotalWeight /2.0, null );
    }

   /** override the process vesicle method 
    */
    public	void		processVesicle( Vesicle v, Synapse s )
    {
	//extract the info needed from the lobe ptr vesicles
    	//map to the new space and carry on as normal
	
	//process the vesicle coming from the synapse s and update the
	//running totals accordingly
	if (v!=null)
	{       
	    switch( v.getType())
	    {
		//incoming vesicle is a learn vesicle.
		//set pointer according to the winner in the output lobe
	        case Vesicle.LEARN_VESICLE:
		        processLearn( v, s );
			break;
		case Vesicle.DRIVE_VESICLE:
			processDrive( v, s );
			break;		        
		case Vesicle.SPECIAL_VESICLE:
			processSpecial( v, s );
			break;
		default:
			;
	    }
	}
    }  

    public	void		processLearn( Vesicle v, Synapse s )
    {
	iLearnTotalWeight += v.getSignalStrength();
    }
    public	void		processDrive( Vesicle v, Synapse s )
    {
	iDriveTotalWeight += v.getSignalStrength();
    }
}
